if (typeof(ko.extensions.webos.palm) == 'undefined')
    ko.extensions.webos.palm = {};

ko.extensions.webos.palm.packageApplication = function(obj)
{
    ko.extensions.webos.project.getConfigInfo({
        onSuccess:function()
        {
            // SRC Folder
            var src = Components.classes["@mozilla.org/file/local;1"].
                             createInstance(Components.interfaces.nsILocalFile);
            src.initWithPath(ko.extensions.webos.project.path);
            src.append("src");
            
            var folder = Components.classes["@mozilla.org/file/local;1"].
                             createInstance(Components.interfaces.nsILocalFile);
            folder.initWithPath(ko.extensions.webos.project.path);
            folder.append("bin");
            if(!folder.exists() || !folder.isDirectory()) // if it doesn't exist, create
                folder.create(Components.interfaces.nsIFile.DIRECTORY_TYPE, 0777);
            
            // Release or Debug Folder
            if(this.json.debuggingEnabled)
                folder.append("debug");
            else
                folder.append("release");
            // Create Release Directory
            if(!folder.exists() || !folder.isDirectory())
                folder.create(Components.interfaces.nsIFile.DIRECTORY_TYPE, 0777);
            
            var cmd = 'palm-package -o "' + folder.path + '" "' + src.path + '"';
            
            var runSvc = Components.classes["@activestate.com/koRunService;1"].
                        createInstance(Components.interfaces.koIRunService);
            
            ko.extensions.webos.palm.cb = function(retvalue, output)
            {
                if (retvalue == 0)
                    obj.onSuccess.call({retval:retvalue});
                else
                    obj.onFailure.call({retval:retvalue});
            };
            
            var appInfo = Components.classes["@mozilla.org/xre/app-info;1"].
                                getService(Components.interfaces.nsIXULRuntime);
            
            var process = runSvc.RunAndNotify(cmd /* command */,
                                              ""  /* cwd */,
                                              ""  /* environment settings */,
                                              ""  /* stdin input */);
        },
        onFailure:function()
        {
            alert(this.error);
        }
    });
};

ko.extensions.webos.palm.newScene = function(obj)
{
    var src = Components.classes["@mozilla.org/file/local;1"].
                     createInstance(Components.interfaces.nsILocalFile);
    src.initWithPath(ko.extensions.webos.project.path);
    src.append("src");
    //palm-generate -t new_scene -p "name=First" ~/projects/Ticker
    var cmd = 'palm-generate -t new_scene -p "name=' + obj.name + '" "' + src.path + '"';
    var runSvc = Components.classes["@activestate.com/koRunService;1"].
                createInstance(Components.interfaces.koIRunService);
    
    ko.extensions.webos.palm.cb = function(retvalue, output)
    {
        if(retvalue == 0)
            obj.onSuccess.call({retval:retvalue});
        else
            obj.onFailure.call({retval:retvalue});
    };
    var process = runSvc.RunAndNotify(cmd /* command */,
                                      ""  /* cwd */,
                                      ""  /* environment settings */,
                                      ""  /* stdin input */);
};

ko.extensions.webos.palm.installApplication = function(obj)
{
    ko.extensions.webos.project.getInfo({
        onSuccess:function()
        {
            var folder = Components.classes["@mozilla.org/file/local;1"].
                             createInstance(Components.interfaces.nsILocalFile);
            folder.initWithPath(ko.extensions.webos.project.path);
            folder.append("bin");
            if(!folder.exists() || !folder.isDirectory()) // if it doesn't exist, create
                folder.create(Components.interfaces.nsIFile.DIRECTORY_TYPE, 0777);
            // Release or Debug Folder
            if(this.json.debuggingEnabled)
                folder.append("debug");
            else
                folder.append("release");
            folder.append(this.json.id + '_' + this.json.version + '_all.ipk');
            
            var cmd = 'palm-install -d ' + obj.device + ' "' + folder.path + '"';
            
            var runSvc = Components.classes["@activestate.com/koRunService;1"].
                        createInstance(Components.interfaces.koIRunService);
            
            ko.extensions.webos.palm.cb = function(retvalue, output)
            {
                if (retvalue == 0)
                    obj.onSuccess.call({retval:retvalue});
                else
                    obj.onFailure.call({retval:retvalue});
            };
            
            var process = runSvc.RunAndNotify(cmd /* command */,
                                              ""  /* cwd */,
                                              ""  /* environment settings */,
                                              ""  /* stdin input */);
        },
        onFailure:function()
        {
            alert(this.error);
        }
    });
};

ko.extensions.webos.palm.launchApplication = function(obj)
{
    ko.extensions.webos.project.getAppInfo({
        onSuccess:function()
        {
            var cmd = 'palm-launch -d ' + obj.device + ' "' + this.json.id + '"';
            
            var runSvc = Components.classes["@activestate.com/koRunService;1"].
                        createInstance(Components.interfaces.koIRunService);
            
            ko.extensions.webos.palm.cb = function(retvalue, output)
            {
                if (retvalue == 0)
                    obj.onSuccess.call({retval:retvalue});
                else
                    obj.onFailure.call({retval:retvalue});
            };
            
            var process = runSvc.RunAndNotify(cmd /* command */,
                                              ""  /* cwd */,
                                              ""  /* environment settings */,
                                              ""  /* stdin input */);
        },
        onFailure:function()
        {
            alert(this.error);
        }
    });
};

ko.extensions.webos.palm.closeApplication = function(obj)
{
    ko.extensions.webos.project.getAppInfo({
        onSuccess:function()
        {
            var cmd = 'palm-launch -d ' + obj.device + ' -c "' + this.json.id + '"';
            
            var runSvc = Components.classes["@activestate.com/koRunService;1"].
                        createInstance(Components.interfaces.koIRunService);
            
            ko.extensions.webos.palm.cb = function(retvalue, output)
            {
                if (retvalue == 0)
                    obj.onSuccess.call({success:true, retval:retvalue});
                else
                    obj.onFailure.call({success:false, retval:retvalue});
            };
            
            var process = runSvc.RunAndNotify(cmd /* command */,
                                              ""  /* cwd */,
                                              ""  /* environment settings */,
                                              ""  /* stdin input */);
        },
        onFailure:function()
        {
            alert(this.error);
        }
    });
};

ko.extensions.webos.palm.removeApplication = function(obj)
{
    ko.extensions.webos.project.getAppInfo({
        onSuccess:function()
        {
            var cmd = 'palm-install -d ' + obj.device + ' -r "' + this.json.id + '"';
            
            var runSvc = Components.classes["@activestate.com/koRunService;1"].
                        createInstance(Components.interfaces.koIRunService);
            
            ko.extensions.webos.palm.cb = function(retvalue, output)
            {
                if (retvalue == 0)
                    obj.onSuccess.call({retval:retvalue});
                else
                    obj.onFailure.call({retval:retvalue});
            };
            
            var process = runSvc.RunAndNotify(cmd /* command */,
                                              ""  /* cwd */,
                                              ""  /* environment settings */,
                                              ""  /* stdin input */);
        },
        onFailure:function()
        {
            alert(this.error);
        }
    });
};

ko.extensions.webos.palm.inspectApplication = function(obj)
{
    ko.extensions.webos.project.getAppInfo({
        onSuccess:function()
        {
            var cmd = 'palm-launch -d ' + obj.device + ' -i "' + this.json.id + '"';
            
            var runSvc = Components.classes["@activestate.com/koRunService;1"].
                                    createInstance(Components.interfaces.koIRunService);
            
            ko.extensions.webos.palm.cb = function(retvalue, output)
            {
                if (retvalue == 0)
                    obj.onSuccess.call({success:true, retval:retvalue});
                else
                    obj.onFailure.call({success:false, retval:retvalue});
            };
            
            var process = runSvc.RunAndNotify(cmd /* command */,
                                              ""  /* cwd */,
                                              ""  /* environment settings */,
                                              ""  /* stdin input */);
        },
        onFailure:function()
        {
            alert(this.error);
        }
    });
};

ko.extensions.webos.palm.emulatorSSH = function(command, input, callback)
{
    ko.extensions.webos.palm.isEmulatorConnected(function(){
        if(this.success)
        {
            var web = Components.classes["@templarian.com/WebOS;1"].
                         createInstance(Components.interfaces.IWebOS);
            web.ssh("localhost",
            5522,
            "root",
            "",
            command,
            input,
            {
                callback:function(success, output){
                    if(success == true)
                        callback.call({success:true,output:output});
                    else
                        callback.call({success:false,output:output});
                }
            });
        }
        else
        {
            callback.call({success:false,output:"Could not connect to device, make sure Developer Mode is on and the device is connected"});
        }
    });
};
ko.extensions.webos.palm.generateCall = function(number, callback)
{
    var web = Components.classes["@templarian.com/WebOS;1"].
                         createInstance(Components.interfaces.IWebOS);
    ko.extensions.webos.command.truncateConsole("Trying - Calling Emulator with number: " + number);
    web.ssh("localhost",
            5522,
            "root",
            "",
            'luna-send -n 1 luna://com.palm.pmradiosimulator/set_incomingcall {\\"number\\":\\"' + number + '\\"}\n',
            "",
            {
                callback:function(success){
                    if(success == true)
                    {
                        ko.extensions.webos.command.appendConsole("Success - Calling Emulator with number: " + number);
                    }
                    else
                    {
                        ko.extensions.webos.command.appendConsole("Failed - Calling Emulator with number: " + number);
                    }
                }
            });
};

ko.extensions.webos.palm.generateSMS = function(number, msg, callback)
{
    var web = Components.classes["@templarian.com/WebOS;1"].
                         createInstance(Components.interfaces.IWebOS);
    ko.extensions.webos.command.truncateConsole("Trying - SMS Emulator with number: " + number + ", message: " + msg);
    web.ssh("localhost",
            5522,
            "root",
            "",
            'luna-send -n 1 luna://com.palm.pmradiosimulator/set_incomingsms {\\"number\\":\\"' + number + '\\",\\"message\\":\\"\'' + msg + '\'\\"}\n',
            "",
            {
                callback:function(success){
                    if(success == true)
                    {
                        ko.extensions.webos.command.appendConsole("Success - SMS Emulator with number: " + number + ", message: " + msg);
                    }
                    else
                    {
                        ko.extensions.webos.command.appendConsole("Failed - SMS Emulator with number: " + number + ", message: " + msg);
                    }
                }
            });
};

ko.extensions.webos.palm.generateFixedGPS = function(latitude, longitude, callback)
{
    var web = Components.classes["@templarian.com/WebOS;1"].
                         createInstance(Components.interfaces.IWebOS);
    ko.extensions.webos.command.truncateConsole("Trying - Fix GPS Emulator with latitude: " + latitude + ", longitude: " + longitude);
    web.ssh("localhost",
            5522,
            "root",
            "",
            'luna-send -n 1 luna://com.palm.pmradiosimulator/set_position {\\"lat\\":\\"' + latitude + '\\",\\"long\\":\\"' + longitude + '\\"}\n',
            "",
            {
                callback:function(success){
                    if(success == true)
                    {
                        ko.extensions.webos.command.appendConsole("Success - Fix GPS Emulator with latitude: " + latitude + ", longitude: " + longitude);
                    }
                    else
                    {
                        ko.extensions.webos.command.appendConsole("Failed - Fix GPS Emulator with latitude: " + latitude + ", longitude: " + longitude);
                    }
                }
            });
};

ko.extensions.webos.palm.setOperatorName = function(name, callback)
{
    var web = Components.classes["@templarian.com/WebOS;1"].
                         createInstance(Components.interfaces.IWebOS);
    ko.extensions.webos.command.truncateConsole("Trying - Operator Name Emulator with name: " + name);
    web.ssh("localhost",
            5522,
            "root",
            "",
            'luna-send -n 1 luna://com.palm.pmradiosimulator/set_operator {\\"operator\\":\\"' + name + '\\"}\n',
            "",
            {
                callback:function(success){
                    if(success == true)
                    {
                        ko.extensions.webos.command.appendConsole("Success - Operator Name Emulator with name: " + name);
                    }
                    else
                    {
                        ko.extensions.webos.command.appendConsole("Failed - Operator Name Emulator with name: " + name);
                    }
                }
            });
};
/**
 *
 * obj = {
 *     path:""
 *     appInfo:{}
 *     onSuccess:function(){}
 * };
 */
ko.extensions.webos.palm.generateApplication = function(obj)
{
    ko.extensions.webos.palm.cb = function(retvalue, output)
    {
        // Get Path
        var appInfo = Components.classes["@mozilla.org/file/local;1"].
                        createInstance(Components.interfaces.nsILocalFile);
        appInfo.initWithPath(obj.path);
        appInfo.append("appinfo.json");
        var appInfoString = ko.extensions.webos.json.toString(obj.appInfo);
        // Save to Path
        var foStream = Components.classes["@mozilla.org/network/file-output-stream;1"].
                         createInstance(Components.interfaces.nsIFileOutputStream);
        foStream.init(appInfo, 0x02 | 0x08 | 0x20, 0666, 0);
        
        var converter = Components.classes["@mozilla.org/intl/converter-output-stream;1"].
                                  createInstance(Components.interfaces.nsIConverterOutputStream);
        converter.init(foStream, "UTF-8", 0, 0);
        converter.writeString(appInfoString);
        converter.close();
        // Handle Callback
        var stdout = output.getStdout();
        if (retvalue == 0)
            obj.onSuccess.call({retval:retvalue, stdout:stdout});
        else
            obj.onFailure.call({retval:retvalue, stdout:stdout});
    };
    var cmd = "palm-generate -p \"{title:'" + obj.appInfo.title.replace(/'/, "\\'") +
                                        "', id:" + obj.appInfo.id +
                                        ", version:'" + obj.appInfo.version +
                                        "'}\" \"" + obj.path + '"';
    var runSvc = Components.classes["@activestate.com/koRunService;1"].
                createInstance(Components.interfaces.koIRunService);
    var process = runSvc.RunAndNotify(cmd /* command */,
                                      ""  /* cwd */,
                                      ""  /* environment settings */,
                                      ""  /* stdin input */);
    //var retvalue = process.wait(-1); /* wait till the process is done */
};

ko.extensions.webos.palm.isEmulatorConnected = function(obj)
{
    ko.extensions.webos.palm.cb = function(retvalue, output)
    {
        var stdout = output.getStdout();
        if (retvalue == 0)
        {
            if(stdout.match(/ tcp /) != null)
                obj.onSuccess.call({retval:retvalue, stdout:stdout});
            else
                obj.onFailure.call({retval:retvalue, stdout:stdout});
        }
        else
        {
            obj.onFailure.call({retval:retvalue, stdout:stdout});
        }
    };
    var runSvc = Components.classes["@activestate.com/koRunService;1"].
                createInstance(Components.interfaces.koIRunService);
    var cmd = "novacom -l";
    var process = runSvc.RunAndNotify(cmd /* command */,
                                      ""  /* cwd */,
                                      ""  /* environment settings */,
                                      ""  /* stdin input */);
};

ko.extensions.webos.palm.isDeviceConnected = function(obj)
{
    ko.extensions.webos.palm.cb = function(retvalue, output)
    {
        var stdout = output.getStdout();
        if (retvalue == 0)
        {
            if(stdout.match(/ usb /) != null)
                obj.onSuccess.call({retval:retvalue, stdout:stdout});
            else
                obj.onFailure.call({retval:retvalue, stdout:stdout});
        }
        else
        {
            obj.onFailure.call({retval:retvalue, stdout:stdout});
        }
    };
    var runSvc = Components.classes["@activestate.com/koRunService;1"].
                createInstance(Components.interfaces.koIRunService);
    var cmd = "novacom -l";
    var process = runSvc.RunAndNotify(cmd /* command */,
                                      ""  /* cwd */,
                                      ""  /* environment settings */,
                                      ""  /* stdin input */);
};